﻿using System.Collections.Generic;
using System.Linq;

namespace Sidvall.CodeGenerator
{
    public class DomainObjectPropertyCollection : System.Collections.ObjectModel.KeyedCollection<string, DomainObjectProperty>
    {
        #region Business Members

        #region Add

        public void Add(string name, string defaultValue)
        {
            var item = new DomainObjectProperty()
            {
                Name = name,
                DefaultValue = defaultValue,
            };
            Add(item);
        }

        #endregion
        #region AddRange

        public void AddRange(IEnumerable<DomainObjectProperty> items)
        {
            if (items == null)
                return;
            foreach (var item in items)
                Add(item);
        }
        public void AddRange(IEnumerable<string> propertyNames)
        {
            if (propertyNames == null)
                return;
            foreach (var name in propertyNames)
            {
                var item = new DomainObjectProperty()
                {
                    Name = name,
                };
                Add(item);
            }
        }
        public void AddRange(params string[] propertyNames)
        {
            AddRange(propertyNames.AsEnumerable());
        }

        #endregion
        #region AddOrGetExisting

        public DomainObjectProperty AddOrGetExisting(DomainObjectProperty item)
        {
            if (item == null)
                return null;
            if (!Contains(item.Name))
            {
                Add(item);
                return item;
            }
            return this[item.Name];
        }

        #endregion
        #region ClearCache

        public void ClearCache()
        {
            foreach (var item in this)
                item.ClearCache();
        }

        #endregion
        #region FindByName

        public DomainObjectProperty FindByName(string name)
        {
            if (Contains(name))
                return this[name];
            return null;
        }

        #endregion
        #region GetKeyForItem

        protected override string GetKeyForItem(DomainObjectProperty item)
        {
            if (item == null)
                throw new System.ArgumentNullException("item");
            return item.Name;
        }

        #endregion
        #region Import

        public void Import(System.Collections.Generic.IEnumerable<DomainObjectProperty> items)
        {
            if (items == null)
                return;
            foreach (var item in items)
            {
                if (Contains(item.Name))
                    this[item.Name].Import(item);
                else
                    Add(item);
            }
        }

        #endregion
        #region InsertItem

        protected override void InsertItem(int index, DomainObjectProperty item)
        {
            if ((item != null) && (this.DomainObject != null))
                item.DomainObject = this.DomainObject;
            base.InsertItem(index, item);
        }

        #endregion
        #region SetItem

        protected override void SetItem(int index, DomainObjectProperty item)
        {
            if ((item != null) && (this.DomainObject != null))
                item.DomainObject = this.DomainObject;
            base.InsertItem(index, item);
        }

        #endregion
        #region ToJson

        public string ToJson()
        {
            var sb = new System.Text.StringBuilder();
            foreach (var item in this)
            {
                if (sb.Length > 0)
                    sb.Append(",");
                sb.Append(Newtonsoft.Json.JsonConvert.SerializeObject(item.Name) + ":" + Newtonsoft.Json.JsonConvert.SerializeObject(item.DefaultValue));
            }
            return sb.ToString();
        }

        #endregion

        #endregion
        #region Helper Members

        #region DomainObject

        private DomainObject _DomainObject;
        private DomainObject DomainObject
        {
            get
            {
                return _DomainObject;
            }
            set
            {
                _DomainObject = value;
                foreach (var item in this)
                    item.DomainObject = value;
            }
        }

        #endregion

        #region SetDomainObject

        internal void SetDomainObject(DomainObject item)
        {
            this.DomainObject = item;
        }

        #endregion

        #endregion
        #region Constructors

        public DomainObjectPropertyCollection()
            : base(System.StringComparer.OrdinalIgnoreCase)
        {
        }

        #endregion
    }
}
